<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/vaadin-material-theme/vaadin-combo-box.html">
<link rel="import" href="../view-app.html">
<link rel="import" href="../style/shared-styles.html">
<script src="../utilizes/formatDate.js"></script>
<dom-module id="view-setup-factory">
    <template>
        <style include="shared-styles app-grid-style">
            :host {
                margin: 10px;
                display: block;
                --app-grid-item-height: 50%;
            }

            @media (min-width: 360px) and (max-width: 768px) {
                :host {
                    --app-grid-columns: 1;
                }
            }

            @media (min-width: 769px) and (max-width: 1024px) {
                :host {
                    --app-grid-columns: 1;
                }
            }

            @media (min-width: 1025px) and (max-width: 1200px) {
                :host {
                    --app-grid-columns: 2;
                }
            }

            @media (min-width: 1201px) {
                :host {
                    --app-grid-columns: 2;
                }
            }

            .operation-day-selector {
                margin: 10px 0;
                padding: 10px 10px 20px 10px;
                border: 1px solid rgba(0, 0, 0, .10);
                border-radius: 5px;
            }

            .operation-day-selector>p {
                margin-bottom: 10px;
                font-size: 0.75rem;
                font-family: var(--paper-font-subhead_-_font-family);
                -webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing);
                line-height: var(--paper-font-subhead_-_line-height);
            }

            paper-checkbox.checkbox {
                padding: 0 5px;
                flex: auto;
                align-content: stretch;
            }
        </style>
        <firebase-auth app-name="smart-mes" id="auth" user="{{user}}"></firebase-auth>
        <firebase-document app-name="smart-mes" id="userData" path="/user/[[user.uid]]" data="{{k}}"></firebase-document>
        <firebase-document app-name="smart-mes" id="factoryProfile" path="/data/[[k.key]]/factoryData/profile" data="{{factoryProfile}}"></firebase-document>
        <firebase-document app-name="smart-mes" id="factoryOperation" path="/data/[[k.key]]/factoryData/operation" data="{{factoryOperation}}"></firebase-document>
        <firebase-document app-name="smart-mes" id="factoryPerformance" path="/data/[[k.key]]/factoryData/performance" data="{{factoryPerformance}}"></firebase-document>
        <firebase-document app-name="smart-mes" id="factorySchedule" path="/data/[[k.key]]/factoryData/schedule" data="{{factorySchedule}}"></firebase-document>
        <app-localstorage-document key="app-lang" data="{{language}}"></app-localstorage-document>
        <ul class="app-grid">
            <li>
                <div class="card">
                    <h1 class="title">{{localize('factory-initialize')}}</h1>
                    <div>
                        <paper-input label="{{localize('factory-name')}}" id="factoryName" value="[[factoryProfile.name]]" type="text" required
                            always-float-label></paper-input>
                        <vaadin-combo-box label="{{localize('factory-type')}}" id="factoryType" value="[[factoryProfile.type]]" items="[[factoryType]]"
                            item-label-path="name" item-value-path="value" loading="[[!factoryType]]" error-message="Invalid Input"
                            required always-float-label='true'>
                            <template>
                                <paper-item>
                                    <paper-icon-item style="padding: 0">
                                        <iron-icon icon="vaadin:factory" slot="item-icon"></iron-icon>
                                        <paper-item-body style="min-height: 0">
                                            <div>[[item.name]]</div>
                                        </paper-item-body>
                                    </paper-icon-item>
                                </paper-item>
                            </template>
                        </vaadin-combo-box>
                        <vaadin-combo-box label="{{localize('production-model')}}" id="productionModel" value="[[factoryProfile.model]]"
                            items="[[productionModel]]" item-value-path="value" item-label-path="name" loading="[[!productionModel]]"
                            error-message="Invalid Input" selected-item="{{selectProductionModel}}" required always-float-label='true'>
                            <template>
                                <paper-item>
                                    <paper-icon-item style="padding: 0">
                                        <iron-icon icon="vaadin:[[item.icon]]" slot="item-icon"></iron-icon>
                                        <paper-item-body two-line style="min-height: 0">
                                            <div readonly>[[item.name]]</div>
                                            <div secondary>[[item.description]]</div>
                                        </paper-item-body>
                                    </paper-icon-item>
                                </paper-item>
                            </template>
                        </vaadin-combo-box>
                        <vaadin-combo-box label="{{localize('station-concurrency')}}" id="concurrency" value="[[factoryProfile.concurrency]]"
                            items="[[concurrencyItems]]" item-value-path="value" item-label-path="value" error-message="Invalid Input"
                            loading="[[!concurrencyItems]]" required always-float-label='true'>
                            <template>
                                <paper-item>
                                    <paper-item-body style="min-height: 0">
                                        <div readonly>[[item.value]]</div>
                                    </paper-item-body>
                                </paper-item>
                            </template>
                        </vaadin-combo-box>
                        <paper-input label="{{localize('operation-start')}}" id="opStart" value="[[factoryOperation.op_start]]" type="time"
                            required pattern="[0-9]{2}:[0-9]{2}" always-float-label></paper-input>
                        <paper-input label="{{localize('operation-end')}}" id="opEnd" value="[[factoryOperation.op_end]]" type="time" required
                            pattern="[0-9]{2}:[0-9]{2}" always-float-label></paper-input>
                        <paper-input label="{{localize('over-time-start')}}" id="otStart" value="[[factoryOperation.ot_start]]" type="time"
                            required pattern="[0-9]{2}:[0-9]{2}" always-float-label></paper-input>
                        <paper-input label="{{localize('over-time-end')}}" id="otEnd" value="[[factoryOperation.ot_end]]" type="time" required
                            pattern="[0-9]{2}:[0-9]{2}" always-float-label></paper-input>

                        <div class="operation-day-selector">
                            <p>{{localize('operation-day')}}</p>
                            <div class="flex-container wrap">
                                <paper-checkbox class="checkbox" tabindex="0" id="sunday" value="sun" noink>Sun</paper-checkbox>
                                <paper-checkbox class="checkbox" tabindex="0" id="monday" value="mon" noink>Mon</paper-checkbox>
                                <paper-checkbox class="checkbox" tabindex="0" id="tuesday" value="tue" noink>Tue</paper-checkbox>
                                <paper-checkbox class="checkbox" tabindex="0" id="wednesday" value="wed" noink>Wed</paper-checkbox>
                                <paper-checkbox class="checkbox" tabindex="0" id="thursday" value="thu" noink>Thu</paper-checkbox>
                                <paper-checkbox class="checkbox" tabindex="0" id="friday" value="fri" noink>Fri</paper-checkbox>
                                <paper-checkbox class="checkbox" tabindex="0" id="saturday" value="sat" noink>Sat</paper-checkbox>
                            </div>
                        </div>
                        <vaadin-combo-box label="{{localize('productivity-optimization')}} (BETA)" id="optimizationType" value="[[factoryPerformance.optimize]]"
                            items="[[optimizationType]]" item-value-path="value" item-label-path="name" loading="[[!optimizationType]]"
                            required always-float-label>
                            <template>
                                <paper-item>
                                    <paper-icon-item style="padding: 0">
                                        <iron-icon icon="vaadin:[[item.icon]]" slot="item-icon"></iron-icon>
                                        <paper-item-body two-line style="min-height: 0">
                                            <div readonly>{{localize(item.value)}}</div>
                                            <div secondary>[[item.description]]</div>
                                        </paper-item-body>
                                    </paper-icon-item>
                                </paper-item>
                            </template>
                        </vaadin-combo-box>
                        <paper-input label="{{localize('standard-acceptable-utilization')}} (30-100%)" id="workerUtilize" value="[[factoryPerformance.au]]"
                            type="number" min="30" max="100" step="1" auto-validate error-message="Input out of range" required
                            always-float-label></paper-input>
                        <paper-input label="{{localize('standard-machine-efficiency')}} (30-100%)" name="machineStandardEfficiency" id="machineStandardEffi"
                            value="[[factoryPerformance.meff]]" type="number" min="30" max="100" step="1" auto-validate
                            error-message="Input out of range" required always-float-label></paper-input>
                        <paper-input label="{{localize('acceptable-waste')}} (0.00-1.00)" id="acceptWaste" value="[[factoryPerformance.aw]]"
                            type="number" min="0" max="1" step="0.01" auto-validate error-message="Input out of range" required
                            always-float-label></paper-input>
                        <vaadin-combo-box label="{{localize('reschedule-interval')}} ({{localize('day')}})" id="scheduleInterval" value="[[factorySchedule.interval]]"
                            items="[[intervalItems]]" item-value-path="value" item-label-path="value" error-message="Invalid Input"
                            required always-float-label>
                            <template>
                                <paper-item>
                                    <paper-item-body style="min-height: 0">
                                        <div readonly>[[item.value]]</div>
                                    </paper-item-body>
                                </paper-item>
                            </template>
                        </vaadin-combo-box>
                        <paper-input label="{{localize('delay-between-station')}} ({{localize('minute')}})" name="stationDelay" id="delayBetweenStation"
                            value="[[factorySchedule.delay]]" type="number" min="0" max="180" step="1" auto-validate
                            error-message="Input out of range" required always-float-label></paper-input>
                        <paper-button on-click="restoreDefault" class="btn" title="Restore Default">
                            {{localize('restore')}}
                        </paper-button>
                        <paper-button on-click="saveValue" class="shamrock btn" title="Save settings">
                            {{localize('save-settings')}}
                        </paper-button>
                    </div>
                </div>
            </li>
            <li>
                <div class="card factory-info" style="margin-bottom: 20px">
                    <h1 class="title">{{localize('factory-information')}}</h1>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('factory-name')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryProfile.name]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('factory-type')}}</p>
                        </li>
                        <li class="right">
                            <p>[[getFactoryType(factoryProfile.type)]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('production-model')}}</p>
                        </li>
                        <li class="right">
                            <p>[[getProductionModel(factoryProfile.model)]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent" id="concurrencyText">
                        <li class="left">
                            <p>{{localize('station-concurrency')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryProfile.concurrency]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator" id="concurrencySeparate"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('operation-start')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryOperation.op_start]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('operation-end')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryOperation.op_end]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('over-time-start')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryOperation.ot_start]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('over-time-end')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryOperation.ot_end]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('operation-day')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryOperation.op_day]]</p>
                        </li>
                    </ul>
                </div>

                <div class="card factory-info" style="margin-top: 20px">
                    <h1 class="title">{{localize('factory-global-standard')}}</h1>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('productivity-optimization')}}</p>
                        </li>
                        <li class="right">
                            <p>{{localize(factoryPerformance.optimize)}}</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('standard-acceptable-utilization')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryPerformance.au]] &#37;</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('standard-machine-efficiency')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryPerformance.meff]] &#37;</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('acceptable-waste')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factoryPerformance.aw]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('reschedule-interval')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factorySchedule.interval]] {{localize('day')}}</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('last-reschedule')}}</p>
                        </li>
                        <li class="right">
                            <p>[[getLastInterval(factorySchedule.start_interval)]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('next-reschedule')}}</p>
                        </li>
                        <li class="right">
                            <p>[[getNextInterval(factorySchedule.start_interval, factorySchedule.interval)]]</p>
                        </li>
                    </ul>
                    <div class="separator-line" role="separator"></div>
                    <ul class="parent">
                        <li class="left">
                            <p>{{localize('delay-between-station')}}</p>
                        </li>
                        <li class="right">
                            <p>[[factorySchedule.delay]] {{localize('minute')}}</p>
                        </li>
                    </ul>
                </div>
            </li>
        </ul>
        <paper-toast id="toastAlert" always-on-top horizontal-align="right" text="{{localize(toastText)}}"></paper-toast>
    </template>
    <script>
        /**
         * @ViewSetupFactory
         * @polymer 
         * @extends {Polymer.Element}
         */
        class ViewSetupFactory extends Polymer.mixinBehaviors([Polymer.AppLocalizeBehavior],
            Polymer.Element) {
            static get is() {
                return 'view-setup-factory'
            }

            static get properties() {
                return {
                    language: String,
                    selectProductionModel: String,
                    toastText: String,
                    factorySchedule: Object,
                    factoryOperation: Object,
                    factoryPerformance: Object,
                    concurrencyItems: {
                        type: Array,
                        value: () => {
                            return [...Array(4)].map((_, i) => ({ "value": i + 2 }))
                        }
                    },
                    intervalItems: {
                        type: Array,
                        value: () => {
                            return [...Array(7)].map((_, i) => ({ "value": i + 1 }))
                        }
                    },
                    optimizationType: {
                        type: Array,
                        value: () => {
                            return [{
                                "name": "Increase Profit",
                                "value": "increase-profit",
                                "icon": "coin-piles",
                                "description": "Maximum profit per order"
                            },
                            {
                                "name": "Reduce Cost",
                                "value": "reduce-cost",
                                "icon": "piggy-bank-coin",
                                "description": "Minimize the cost per order"
                            },
                            {
                                "name": "Disabled",
                                "value": "disabled",
                                "icon": "close",
                                "description": "No optimization"
                            }
                            ]
                        }
                    },
                    productionModel: {
                        type: Array,
                        value: () => {
                            return [{
                                "name": 'Serial',
                                "value": "serial",
                                "icon": "file-tree-sub",
                                "description": "Single part product"
                            },
                            {
                                "name": "Parallel",
                                "value": "parallel",
                                "icon": "file-tree",
                                "description": "Single part product"
                            },
                            {
                                "name": "Single Multi-Component",
                                "value": "multi",
                                "icon": "tree-table",
                                "description": "Multi parts product"
                            }
                            ]
                        }
                    },
                    factoryType: {
                        type: Array,
                        value: () => {
                            return [{
                                "name": "Job Shop",
                                "value": "jobshop"
                            }]
                        }
                    }
                }
            }

            static get observers() {
                return [
                    '_isSerialModel(selectProductionModel.value)',
                    '_setOperationDay(factoryOperation.op_day)',
                    'getNextInterval(factorySchedule.start_interval, factorySchedule.interval)'
                ]
            }

            connectedCallback() {
                super.connectedCallback()
                this.loadResources(this.resolveUrl('../../data/locales.json'))
            }

            saveValue() {
                const fn = this.$.factoryName.value
                const ft = this.$.factoryType.value
                const mod = this.$.productionModel.value
                const con = this.$.concurrency.value
                const aw = this.$.acceptWaste.value
                const au = this.$.workerUtilize.value
                const opt = this.$.optimizationType.value
                const meff = this.$.machineStandardEffi.value
                const inte = this.$.scheduleInterval.value
                const delay = this.$.delayBetweenStation.value
                const op_start = this.$.opStart.value
                const op_end = this.$.opEnd.value
                const ot_start = this.$.otStart.value
                const ot_end = this.$.otEnd.value
                this.operationDay = []
                if (this.$.monday.checked) this.push('operationDay', 'mon')
                if (this.$.tuesday.checked) this.push('operationDay', 'tue')
                if (this.$.wednesday.checked) this.push('operationDay', 'wed')
                if (this.$.thursday.checked) this.push('operationDay', 'thu')
                if (this.$.friday.checked) this.push('operationDay', 'fri')
                if (this.$.saturday.checked) this.push('operationDay', 'sat')
                if (this.$.sunday.checked) this.push('operationDay', 'sun')
                const op_day = this.operationDay.toString()

                if (fn && ft && mod && opt && aw && au && inte && meff && op_start &&
                    op_end && op_day && ot_start && ot_end && delay &&
                    this.$.workerUtilize.validate() && this.$.machineStandardEffi.validate() && this.$.acceptWaste
                        .validate() && this.$.scheduleInterval.validate()) {
                    this.set('factoryProfile.name', fn)
                    this.set('factoryProfile.type', ft)
                    this.set('factoryProfile.model', mod)
                    if (con) {
                        this.set('factoryProfile.concurrency', con)
                    } else {
                        this.set('factoryProfile.concurrency', 2)
                    }
                    this.set('factoryPerformance.optimize', opt)
                    this.set('factoryPerformance.aw', aw)
                    this.set('factoryPerformance.au', au)
                    this.set('factoryPerformance.meff', meff)
                    this.set('factorySchedule.interval', inte)
                    this.set('factorySchedule.delay', delay)
                    this.set('factoryOperation.op_start', op_start)
                    this.set('factoryOperation.op_end', op_end)
                    this.set('factoryOperation.op_day', op_day)
                    this.set('factoryOperation.ot_start', ot_start)
                    this.set('factoryOperation.ot_end', ot_end)
                    this.toastText = 'notification-save-factory-information-successful'
                    this.$.toastAlert.open()
                    this.set('k.setup', true)
                } else {
                    this.toastText = 'notification-error-incomplete-input'
                    this.$.toastAlert.open()
                }
            }

            restoreDefault() {
                this.$.factoryName.value = 'Sample factory'
                this.$.factoryType.value = 'jobshop'
                this.$.productionModel.value = 'parallel'
                this.$.concurrency.value = 2
                this.$.optimizationType.value = 'disabled'
                this.$.acceptWaste.value = 0.02
                this.$.workerUtilize.value = 85
                this.$.machineStandardEffi.value = 75
                this.$.scheduleInterval.value = 1
                this.$.delayBetweenStation.value = 10
                this.$.opStart.value = '08:00'
                this.$.opEnd.value = '17:00'
                this.$.otStart.value = '19:00'
                this.$.otEnd.value = '21:00'
                this.$.monday.checked = true
                this.$.tuesday.checked = true
                this.$.wednesday.checked = true
                this.$.thursday.checked = true
                this.$.friday.checked = true
                this.$.saturday.checked = false
                this.$.sunday.checked = false
            }

            getNextInterval(last_timestamp, interval) {
                if (!last_timestamp || !interval) return 0
                const current = Math.floor(Date.now() / 1000)
                const diff = (current - last_timestamp)
                const range = (interval * 24 * 60 * 60) // convert day to seconds
                if (diff <= range) { // if diff still less than the day interval
                    let nextIntervalTimeStamp = (last_timestamp * 1000) + (range * 1000)
                    return dateFromTimeStamp(nextIntervalTimeStamp)
                } else { // else if diff exceed the day interval then set new start interval 
                    this.set('factorySchedule.start_interval', current)
                    let nextIntervalTimeStamp = (current * 1000) + (range * 1000)
                    return dateFromTimeStamp(nextIntervalTimeStamp)
                }
            }

            getLastInterval(last_timestamp) {
                if (!last_timestamp) return 0
                return dateFromTimeStamp(last_timestamp * 1000)
            }

            getFactoryType(factory_type) {
                if (!factory_type) return 'N/A'
                switch (factory_type) {
                    case 'jobshop':
                        return 'Job Shop'
                    case 'flowshop':
                        return 'Flow Shop'
                    case 'hybrid':
                        return 'Hybrid (Job + Flow)'
                    default:
                        return 'N/A'
                }
            }

            getProductionModel(production_model) {
                if (!production_model) return 'N/A'
                switch (production_model) {
                    case 'serial':
                        return 'Serial'
                    case 'parallel':
                        return 'Parallel'
                    case 'multi':
                        return 'Multi-Component'
                    default:
                        return 'N/A'
                }
            }

            _setOperationDay(op_day) {
                if (op_day) {
                    let opDayArr = op_day.split(',')
                    this.$.monday.checked = opDayArr.includes('mon')
                    this.$.tuesday.checked = opDayArr.includes('tue')
                    this.$.wednesday.checked = opDayArr.includes('wed')
                    this.$.thursday.checked = opDayArr.includes('thu')
                    this.$.friday.checked = opDayArr.includes('fri')
                    this.$.saturday.checked = opDayArr.includes('sat')
                    this.$.sunday.checked = opDayArr.includes('sun')
                }
            }

            _isSerialModel(production_model) {
                if (production_model === 'parallel') {
                    this.$.concurrency.hidden = false
                    this.$.concurrency.disabled = false
                    this.$.concurrencyText.hidden = false
                    this.$.concurrencySeparate.hidden = false
                } else {
                    this.$.concurrency.hidden = true
                    this.$.concurrency.disabled = true
                    this.$.concurrencyText.hidden = true
                    this.$.concurrencySeparate.hidden = true
                }
            }
        }
        customElements.define(ViewSetupFactory.is, ViewSetupFactory)
    </script>
</dom-module>